﻿using System;
using System.Collections.Generic;
using System.Text;
using FieldLib;
using FieldDevice.ModBus;
namespace FieldDevice.Emulation
{
    public abstract class DeviceEmulator
    {
        public DeviceEmulator(ushort address)
        {
            this.Address = address;
        }

        public ushort Address { get; set; }
        public abstract byte[] ProcessModBusPacket(ModBusPacket packet);
        //{
        //    throw new NotImplementedException("Should override this virtual method");
        //}

        public  ModBusPacket CRCVerify(ModBusPacket verify)
        {
            ModBusPacket tmpMod = verify;
            byte CRCHi = 0xFF;
            byte CRCLo = 0xFF;
            byte CL = 0x01;
            byte CH = 0xA0;
            byte SaveHi;
            byte SaveLo;
            CRCLo ^= verify.DataAddressLow;
            for (int Flag = 0; Flag <= 7; Flag++)
            {
                SaveHi = CRCHi;
                SaveLo = CRCLo;
                CRCHi = (byte)(CRCHi >> 1);      //高位右移一位 
                CRCLo = (byte)(CRCLo >> 1);      //低位右移一位 
                if ((SaveHi & 0x01) == 0x01) //如果高位字节最后一位为1 
                {
                    CRCLo = (byte)(CRCLo | 0x80);   //则低位字节右移后前面补1 
                }             //否则自动补0 
                if ((SaveLo & 0x01) == 0x01) //如果LSB为1，则与多项式码进行异或 
                {
                    CRCHi = (byte)(CRCHi ^ CH);
                    CRCLo = (byte)(CRCLo ^ CL);
                }
            }

            CRCLo ^= verify.DataAddressHi;
            for (int Flag = 0; Flag <= 7; Flag++)
            {
                SaveHi = CRCHi;
                SaveLo = CRCLo;
                CRCHi = (byte)(CRCHi >> 1);      //高位右移一位 
                CRCLo = (byte)(CRCLo >> 1);      //低位右移一位 
                if ((SaveHi & 0x01) == 0x01) //如果高位字节最后一位为1 
                {
                    CRCLo = (byte)(CRCLo | 0x80);   //则低位字节右移后前面补1 
                }             //否则自动补0 
                if ((SaveLo & 0x01) == 0x01) //如果LSB为1，则与多项式码进行异或 
                {
                    CRCHi = (byte)(CRCHi ^ CH);
                    CRCLo = (byte)(CRCLo ^ CL);
                }
            }


            CRCLo ^= verify.DataNumberLow;
            for (int Flag = 0; Flag <= 7; Flag++)
            {
                SaveHi = CRCHi;
                SaveLo = CRCLo;
                CRCHi = (byte)(CRCHi >> 1);      //高位右移一位 
                CRCLo = (byte)(CRCLo >> 1);      //低位右移一位 
                if ((SaveHi & 0x01) == 0x01)       //如果高位字节最后一位为1 
                {
                    CRCLo = (byte)(CRCLo | 0x80);   //则低位字节右移后前面补1 
                }                                   //否则自动补0 
                if ((SaveLo & 0x01) == 0x01)    //如果LSB为1，则与多项式码进行异或 
                {
                    CRCHi = (byte)(CRCHi ^ CH);
                    CRCLo = (byte)(CRCLo ^ CL);
                }
            }


            CRCLo ^= verify.DataNumberHi;
            for (int Flag = 0; Flag <= 7; Flag++)
            {
                SaveHi = CRCHi;
                SaveLo = CRCLo;
                CRCHi = (byte)(CRCHi >> 1);      //高位右移一位 
                CRCLo = (byte)(CRCLo >> 1);      //低位右移一位 
                if ((SaveHi & 0x01) == 0x01) //如果高位字节最后一位为1 
                {
                    CRCLo = (byte)(CRCLo | 0x80);   //则低位字节右移后前面补1 
                }             //否则自动补0 
                if ((SaveLo & 0x01) == 0x01) //如果LSB为1，则与多项式码进行异或 
                {
                    CRCHi = (byte)(CRCHi ^ CH);
                    CRCLo = (byte)(CRCLo ^ CL);
                }
            }
            tmpMod.CRCH = CRCHi;
            tmpMod.CRCL = CRCLo;

            return tmpMod;

        }

        public byte[] PacketToFrame(ModBusPacket packet)
        {
            byte[] result = new byte[520];
            result[0]=packet.SlaveAddress;
            result[1] = packet.Function;

            return result;
        
        }
    }

}
